<?php
/**
 * DonReY Documentation Page generator / display
 */
class Controller_Page extends DRY\Application\Controller_base
{
	private $page_title;

	private $page_selector;

	private $textiledoc;

	/**
	 * Struct XML object (structure.xml)
	 * @var SimpleXMLElement
	 */
	private $struct;

	public function Execute()
	{
		if($this->_route[0]!='error404') {

			// compress route into page url_id
			if(empty($this->_route[1]) || $this->_route[1] == 'donrey')
				$this-> page_selector = 'donrey';
			else
				$this-> page_selector = 'donrey/'.$this->_route[1];

			// Determine if page exists (in structure.xml) using xpath query
			$this-> struct = simplexml_load_file("../structure.xml");
			$page = $this-> struct-> xpath('/'.$this-> page_selector);
			if(!empty($page)) {
				$page = $page[0]; // all values are unique here, so the only one found is the correct one.
				$this-> page_title = (string)$page['title'];

				$rootpath = (string)DRY\core::$CFG-> doc-> rootpath;
				// check if the corresponding .textile and .html files exists
				$pagepath = $rootpath. $page['file'];

				if(file_exists($pagepath.'.textile')) {
					// html yes
					$pagetextilefile = new SplFileInfo($pagepath.'.textile');

					if(file_exists($pagepath.'.html')) {
						// html yes
						$pagehtmlfile = new SplFileInfo($pagepath.'.html');

						if($pagehtmlfile-> getMTime() >= $pagetextilefile-> getMTime())
							// found, html is newer, so we can use cache
							return readfile($pagepath.'.html');
					}
					// doesn't exist or not newer, we must create
					$this-> textiledoc = $pagepath.'.textile';

					ob_start();
					echo DRY\core::layout()-> render('page.html', $this);
					file_put_contents($pagepath.'.html', ob_get_flush());
					ob_end_flush();

				} else {
					// oops, page not yet written even if it's in structure.xml
					echo DRY\core::layout()-> render('error404.html');
					return;
				}

			} else {
				echo DRY\core::layout()-> render('error404.html');
				return;
			}
		} else {
			echo DRY\core::layout()-> render('error404.html');
		}

	}

	public function prepare_General_String($which)
	{
		// TODO: Relative paths instead of absolute paths, so this works even when loading HTML files directly (instead of hosting them on a server)
		$drytpl = DRY\core::render()-> factory_Transform('drytemplate');
		switch($which) {
			case 'title':
				return $this-> page_title;
			case 'csspath':
				// TODO: Calculate relative CSS path instead of the absolute one
				return "/Documentation/";
			case 'docpage':
				$textile = DRY\core::render()-> factory_Transform('textile');
				return $textile-> render_String($drytpl-> render_String(file_get_contents($this-> textiledoc)));
			case 'breadcrumbs':

				// display breadcrumbs only when in root
				if($this-> page_selector != 'donrey') {
					$break = explode('/', $this-> page_selector);
					$bc = array(
						array(
							'title'=> "DonReY Framework ".$this-> struct['title'],
							'link'=> "/documentation/donrey.html"
						)
					);
					for($c = 2; $c < count($break); $c++) {
						$frag = array_slice($break, 0, $c);
						$nodes = $this-> struct-> xpath('/'.implode('/',$frag));

						array_shift($frag);
						$bc_elem = array(
							'title'=> (string)$nodes[0]['title'],
							'link'=> '/documentation/'.implode('/',$frag).'.html'
						);
						$bc[]=$bc_elem;
					}
					// add the last node, but not as a link
					$bc[] = array(
						'title'=> $this-> page_title,
						'nolink'=> true
					);
					$data = array(
						'bc' => $bc
					);
					return $drytpl-> render_File("breadcrumbs.tpl", $data);
				}
		}
	}
}
